import EChartComponent, { EChartRef } from "@/components/EChartComponent";
import React, { useState, useEffect, useRef } from "react";
import { getOption } from "./deviceTemplateChart";
import {
  ToChartSeries,
  getOptionValueFromTable,
  GroupBy,
  HearderType,
  GetMinMaxByKey,
  DateformatDate,
  FindPathFromKey,
} from "@/common/common";

import {
  getDeviceRegisterRecord,
  getDeviceRegisterRecordFromDay,
  getGroupDetail,
  getGroupExtensRegister,
  keys,
} from "./httpApi";
import { DeviceInfoFeild } from "./deviceListsFields";
import {
  Button,
  Card,
  DatePicker,
  DatePickerProps,
  Flex,
  Input,
  message,
  Modal,
  Radio,
  Select,
  Space,
  Switch,
  TimePicker,
} from "antd";
import { httpClient } from "@/common/httpClient";
interface IProps {}

const echartRef = React.createRef<EChartRef>();
const echartRef1 = React.createRef<EChartRef>();
import type { Dayjs } from "dayjs";
import dayjs from "dayjs";
import quarterOfYear from "dayjs/plugin/quarterOfYear";
dayjs.extend(quarterOfYear);
const { RangePicker } = DatePicker;

import { CheckboxGroupProps } from "antd/es/checkbox";
import { Group } from "../group/groupFields";

interface deviceTemplateProps {
  groupId: number;
}
type PickerMode = "day" | "month" | "year" | "week" | "quarter";
const inactiveTime = 5 * 60;
let t: any;
let historeDatas: any = [];
let start = "00:00:00";
let end = "23:59:59";
const RegisterValuePage: React.FC<any> = ({
  data,
  deviceId,
  date = DateformatDate(new Date(), "YYYY-MM-DD"),
}) => {
  const chartRefs = useRef<React.RefObject<EChartRef>[]>([]);

  let lastReqTime = DateformatDate(new Date(), "HH:mm:ss");
  const setChartData = (values: any[], key: number) => {
    let historeData = historeDatas[key];
    if (chartRefs?.current) chartRefs.current[key].current?.setLoading(true);
    getDeviceRegisterRecord(JSON.stringify(values), deviceId, {
      createdAt: JSON.stringify([date + " " + start, date + " " + end]),
    }).then((res) => {
      if (res && res.length == 0) return;
      historeData = [...historeData, ...(res || [])];
      let groupData = GroupBy(historeData, "registerName", "registerValue");
      let chartSeries = groupData.map((v: any) => {
        return ToChartSeries(v.name, "line", v.lists);
      });
      let times = historeData.map((v: any) =>
        DateformatDate(v.createdAt, "HH:mm:ss")
      );
      times = [...new Set(times)].sort();
      chartRefs.current[key].current?.setOptions(getOption(chartSeries, times));
      chartRefs.current[key].current?.setLoading(false);
    });
  };

  useEffect(() => {
    data.forEach((item: any, key: number) => {
      //多个组
      let values = item.resLabelArray.map((v: any) => v.value, end);
      if (values.length > 0) {
        if (!historeDatas[key]) historeDatas[key] = [];
        if (!date) date = DateformatDate(new Date(), "YYYY-MM-DD");
        setChartData(values, key);
        if (date == DateformatDate() && !t) {
          t = setInterval(() => {
            start = lastReqTime;
            lastReqTime = DateformatDate(new Date(), "HH:mm:ss");
            setChartData(values, key);
          }, 1000 * inactiveTime);
        }
      }
    });
  }, [data, date]);
  //图表
  return (
    <div style={{ display: "flex" }}>
      {data.map((v: any, key: any) => {
        chartRefs.current[key] = React.createRef<EChartRef>();
        return (
          <div style={{ flex: 1, border: "1px solid #ccc", padding: "10px" }}>
            <div>
              <h2>{v.title}</h2>
              <EChartComponent ref={chartRefs.current[key]} />
            </div>
          </div>
        );
      })}
    </div>
  );
};
const setValue = (data: any, values: any) => {
  data.forEach((v: any) => {
    v.resLabelArray.forEach((v1: any) => {
      if (Object.keys(values).includes(v1.value)) {
        v1["valueData"] = values[v1.value];
      }
    });
    if (v.child && v.child.length > 0) {
      setValue(v.child, values);
    }
  });
};
const getValue = (data: any, key: string, obj: any = {}) => {
  data.forEach((v: any) => {
    v.resLabelArray.forEach((v1: any) => {
      if (v1.isEdit) obj[v1[key]] = v1.valueData.toString();
    });
    if (v.child && v.child.length > 0) {
      getValue(v.child, key, obj);
    }
  });
  return obj;
};
const WriteRegisterPage: React.FC<any> = ({
  data,
  deviceId,
  recoded,
  groupData,
}) => {
  const [WriteRegisterValues, setWriteRegisterValues] = useState<any>(data);
  const [encryptedGCM, setEncryptedGCM] = useState<any>("");
  const onSubmit = async () => {
    let values: Record<string, any> = getValue(WriteRegisterValues, "value");
    //判断是密码
    let dynamicRule = JSON.parse(groupData.dynamicRule);
    if (dynamicRule.pwd) {
      let param = {
        id: dynamicRule.pwd_register_id,
        groupId: recoded.groupId,
        slaveId: recoded.slaveAddress,
        deviceId: recoded.deviceId,
        mode: "W",
        value: dynamicRule.pwd,
      };
      // 用户密码验证
      let res1 = await httpClient.post("/admin/device_register/send", param, {
        headers: { "Content-Type": HearderType[0] },
      });
      if (res1.data.data.computed[0].Value != 1) {
        return message.error("密码验证失败");
      }
    }
    let res = httpClient
      .post(
        "/admin/device_register/sendWrite",
        {
          id: 1,
          groupId: recoded.groupId,
          slaveId: recoded.slaveAddress,
          deviceId: recoded.deviceId,
          mode: "W",
          value: "",
          values: JSON.stringify(values),
          encrypted: encryptedGCM,
        },
        {
          headers: { "Content-Type": HearderType[0] },
        }
      )
      .then((res: any) => {});
  };
  useEffect(() => {
    if (data.length != 0 && WriteRegisterValues.length == 0) {
      let values = FindPathFromKey(data, "resLabelArray").map(
        (v: any) => v.value
      );
      let res = httpClient
        .post(
          "/admin/device_register/sendManys",
          {
            id: 1,
            groupId: recoded.groupId,
            slaveId: recoded.slaveAddress,
            deviceId: recoded.deviceId,
            mode: "R",
            value: JSON.stringify(values),
          },
          {
            headers: { "Content-Type": HearderType[0] },
          }
        )
        .then((res: any) => {
          setEncryptedGCM(res.data.data.encryptedGCM);
          //递归赋值
          setValue(data, res.data.data.values);
          setWriteRegisterValues(data);
        });
    }
  }, [data]);
  // if (data.length > 0) {
  // const { max, min, minData } = GetMinMaxByKey(data, "registerNum");
  const setItems = (data: any, code = "") => {
    if (data.length === 0) return <></>;

    return (
      <div className={"writeTree" + code.length}>
        {data.map((v1: any) => (
          <div>
            <React.Fragment key={v1.title}>
              <h4 style={{ color: "red" }}>{code + v1.title}</h4>
              {v1.resLabelArray.map((v2: any) => {
                return (
                  <div style={{ margin: "15px" }}>
                    <div style={{ color: "blue", marginBottom: "15px" }}>
                      {v2.label}(
                      {v2.extendsJson.scope.min +
                        "~" +
                        v2.extendsJson.scope.max}
                      ) :
                    </div>
                    <Space size={10}>
                      {(v2.extendsJson?.options || []).length == 0 && (
                        <Input
                          min={v2.extendsJson.scope.min}
                          max={v2.extendsJson.scope.max}
                          value={v2.valueData}
                          onChange={(e) => {
                            v2.isEdit = true;
                            v2.valueData = e.target.value;
                            setWriteRegisterValues([...WriteRegisterValues]);
                          }}
                        />
                      )}
                      {(v2.extendsJson?.options || []) > 0 && (
                        <Select
                          style={{ width: "200px" }}
                          value={v2.valueData}
                          options={v2.extendsJson.options}
                          onChange={(e) => {
                            v2.isEdit = true;
                            v2.valueData = e;
                            setWriteRegisterValues([...WriteRegisterValues]);
                          }}
                        />
                      )}
                    </Space>
                  </div>
                );
              })}

              {v1.child && setItems(v1.child, code + "-")}
            </React.Fragment>
          </div>
        ))}
      </div>
    );
  };

  return (
    <div>
      {setItems(WriteRegisterValues)}
      <Button
        type="primary"
        onClick={() => onSubmit()}
        style={{ margin: "20px 0" }}
      >
        确认写入
      </Button>
    </div>
  );
  // }
  // return <div></div>;
};
const TotalRegisterPage: React.FC<any> = ({
  data,
  deviceId,
  date,
  dateType,
}) => {
  useEffect(() => {
    echartRef1.current?.setLoading(true);
    let values = data.map((v: any) => v.registerId);
    if (values.length > 0) {
      getDeviceRegisterRecordFromDay(
        dateType,
        date[dateType],
        values,
        deviceId
      ).then((res) => {
        if (!res || res.length == 0) return message.error("无数据");
        let groupData = res;
        groupData = GroupBy(res, "name", "value");
        let chartSeries = groupData.map((v: any) => {
          return ToChartSeries(v.name, "bar", v.lists);
        });

        let times = res.map((v: any) => {
          if (dateType == "week" || dateType == "month") {
            return DateformatDate(v.date);
          } else if (dateType == "quarter") {
            return v.quarter;
          } else {
            return v.month + "月";
          }
        });
        times = [...new Set(times)].sort();

        const op = getOption(chartSeries, times);
        echartRef1.current?.clear();
        echartRef1.current?.setOptions(getOption(chartSeries, times));
      });
      echartRef1.current?.setLoading(false);
    }
  }, [data, date, dateType]);
  //图表
  return (
    <div>
      <EChartComponent ref={echartRef1} />
    </div>
  );
};
const toControlRegisterDom = (data: any[], onChange: any) => {
  return data.map((v: any) => (
    <div key={v.title}>
      <h5>{v.title}</h5>
      {v.resLabelArray.map((v1: any) => (
        <div key={v1.label}>
          <span>{v1.label}</span>
          <Switch
            defaultChecked
            checkedChildren={
              v1.extendsJson?.options[0]?.choices[0]?.label || ""
            }
            unCheckedChildren={
              v1.extendsJson?.options[0]?.choices[1]?.label || ""
            }
            onChange={(e) => {
              onChange(e, v1.extendsJson?.options[0]?.choices, v1.registerId);
            }}
          />
        </div>
      ))}
      {v.child && toControlRegisterDom(v.child, onChange)}
    </div>
  ));
};

const ControlRegisterPage: React.FC<any> = ({
  data = [],
  deviceId,
  recoded,
}) => {
  const onChange = (e: any, datas: any, registerId: number) => {
    let index = e ? 0 : 1;
    Modal.confirm({
      title: `确定要执行此操作【${datas[index].label}】吗？`,
      content: "请确认是否执行此操作",
      okText: "确定",
      cancelText: "取消",
      onOk: async () => {
        await httpClient.post(
          "/admin/device_register/send",
          {
            id: registerId,
            groupId: recoded.groupId,
            slaveId: recoded.slaveAddress,
            deviceId: recoded.deviceId,
            mode: "C",
            value: datas[index].value.toString(),
          },
          {
            headers: { "Content-Type": HearderType[0] },
          }
        );
      },
    });
  };

  return <div>{toControlRegisterDom(data, onChange)}</div>;
};
const DeviceTemplate: React.FC<{
  recoded?: DeviceInfoFeild | undefined;
  modalIsClose: boolean;
}> = ({
  //使用REF暴露
  recoded,
  modalIsClose,
}) => {
  const [registerValue, setRegisterValue] = useState([]);
  const [writeRegister, setWriteRegister] = useState([]);
  const [totalRegister, setTotalRegister] = useState([]);
  const [controlRegister, setControlRegister] = useState([]);
  const [choiceDate, setChoiceDate] = useState("");
  const [dateType, setDateType] = useState<PickerMode>("week");
  const [groupData, setGroupData] = useState<[Group]>();
  const [RangeChoiceDate, setRangeChoiceDate] = useState<
    Record<PickerMode, string[] | string>
  >({
    day: [
      dayjs().startOf("month").format("YYYY-MM-DD"),
      dayjs().endOf("month").format("YYYY-MM-DD"),
    ],
    week: DateformatDate(),
    month: dayjs().startOf("month").format("YYYY-MM-DD"),
    quarter: dayjs().startOf("quarter").format("YYYY-MM-DD"),
    year: dayjs().startOf("year").format("YYYY-MM-DD"),
  });
  useEffect(() => {
    getGroupDetail(recoded?.groupId || 0).then((res) => {
      setGroupData(res);
    });
  }, []);

  useEffect(() => {
    if (t && modalIsClose) clearInterval(t);
  }, [modalIsClose]);

  const onChange = (date: any, dateString: string | string[]) => {
    historeDatas.forEach((v: any, k: number) => {
      historeDatas[k] = [];
    });
    start = "00:00:00";
    end = "23:59:59";
    clearInterval(t);
    if (typeof dateString === "string") setChoiceDate(dateString);
  };
  const RangePickerOnChange = (date: any, dateString: string | string[]) => {
    RangeChoiceDate[dateType] = dateString;
    setRangeChoiceDate({ ...RangeChoiceDate });
  };
  useEffect(() => {
    getGroupExtensRegister(recoded?.groupId || 0).then((e) => {
      setRegisterValue(e.readRegister);
      setWriteRegister(e.writeRegister);
      setTotalRegister(e.totalRegister);
      setControlRegister(e.controlRegister);
    });
  }, []);
  const options: CheckboxGroupProps<string>["options"] = [
    { label: "周", value: "week" },
    { label: "月", value: "month" },
    { label: "季", value: "quarter" },
    { label: "年", value: "year" },
  ];

  return (
    <div>
      <div>
        {keys.map((v) => {
          return (
            <div>
              <Card title={v.label} style={{ margin: "30px 0" }}>
                {v.value === "readRegister" && (
                  <div>
                    <DatePicker
                      onChange={onChange}
                      needConfirm
                      defaultValue={dayjs()}
                      maxDate={dayjs()}
                    />
                    <RegisterValuePage
                      data={registerValue}
                      date={choiceDate}
                      deviceId={recoded?.deviceId}
                    />
                  </div>
                )}
                {v.value === "writeRegister" && (
                  <WriteRegisterPage
                    data={writeRegister}
                    groupData={groupData}
                    deviceId={recoded?.deviceId}
                    recoded={recoded}
                  />
                )}
                {v.value === "totalRegister" && (
                  <>
                    <Space>
                      <Radio.Group
                        buttonStyle="solid"
                        optionType="button"
                        value={dateType}
                        options={options}
                        onChange={(e) => {
                          setDateType(e.target.value);
                        }}
                      />

                      {dateType === "day" && (
                        <RangePicker
                          onChange={RangePickerOnChange}
                          needConfirm
                          defaultValue={[
                            dayjs(RangeChoiceDate.day[0]),
                            dayjs(RangeChoiceDate.day[1]),
                          ]}
                        />
                      )}
                      {dateType != "day" && (
                        <DatePicker
                          picker={dateType || "month"}
                          onChange={RangePickerOnChange}
                          needConfirm
                          defaultValue={dayjs(
                            RangeChoiceDate[dateType] as string
                          )}
                        />
                      )}
                    </Space>
                    <TotalRegisterPage
                      data={totalRegister}
                      dateType={dateType}
                      date={RangeChoiceDate}
                      deviceId={recoded?.deviceId}
                    />
                  </>
                )}
                {v.value === "controlRegister" && (
                  <ControlRegisterPage
                    data={controlRegister}
                    deviceId={recoded?.deviceId}
                    recoded={recoded}
                  />
                )}
              </Card>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default DeviceTemplate;
